package com.smart.upload.service.impl;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Component;

import com.smart.upload.bean.FileInfo;
import com.smart.upload.bean.UserInfo;
import com.smart.upload.exception.UploadException;
import com.smart.upload.service.UploadService;
import com.smart.upload.service.UserInfoService;
import com.smart.upload.util.UploadConfigUtils;
import com.smart.util.DateUtils;
import com.smart.util.FileUtils;
import com.smart.util.StringUtils;

/**
 * <b>Description:本地文件上传</b><br>
 * 
 * @author 唐海洋
 * @version 1.0 2016-8-5 下午2:33:23
 */
@Component("localFileUploadService")
public class LocalFileUploadServiceImpl implements UploadService {

	/** 斜杠 */
	private static final String SPRIT = "/";

	// 文件上传目录，默认目录为webroot下的upload文件夹
	private String baseDir = "upload/";

	@Resource
	private UserInfoService userInfoService;

	public LocalFileUploadServiceImpl() {
	}

	public LocalFileUploadServiceImpl(String baseDir) {
		if (StringUtils.isNotBlank(baseDir)) {
			if (baseDir.endsWith(SPRIT)) {
				this.baseDir = baseDir;
			} else {
				this.baseDir = baseDir + SPRIT;
			}
		}
	}

	@Override
	public FileInfo save(File file, String fileName) {

		UserInfo userInfo = userInfoService.get();

		// 1.生成最终文件上传目录格式为"upload/userBasePath/path/"
		String dirPth = baseDir + userInfo.getBasePath()
				+ generateUploadDirPath();

		// 2.创建目录
		File saveFileFolder = createFileFolder(dirPth);

		// 3.生成新的文件名
		String newFileName = generateNewFileName(FilenameUtils
				.getExtension(fileName));

		// 4.保存文件
		saveFile(file, new File(saveFileFolder, newFileName));

		// 5.返回数据
		FileInfo r = new FileInfo();
		r.setExt(FilenameUtils.getExtension(fileName));
		r.setFilename(newFileName);
		r.setFileSize(file.length() / 1024);
		r.setOriginalFilename(fileName);
		r.setPath(UploadConfigUtils.getDomainMapList().get(0).getDomain()
				+ dirPth + newFileName);

		return r;
	}

	/**
	 * Description:保存文件
	 * 
	 * @author 唐海洋
	 * @Version 1.0 2016-8-9下午5:03:52
	 * @param fromFile
	 *            源文件
	 * @param toFile
	 *            目标文件
	 */
	protected void saveFile(File fromFile, File toFile) {
		try {
			FileUtils.copy(fromFile, toFile);
		} catch (IOException e) {
			throw new UploadException(e);
		}
	}

	/**
	 * Description:级联创建将要保存文件的文件路径
	 * 
	 * @author 唐海洋
	 * @Version 1.0 2016-8-9下午5:04:21
	 * @param fileFolderPath
	 *            文件夹路径
	 * @return 用于保存上传文件的文件夹
	 */
	protected File createFileFolder(String fileFolderPath) {

		String absolutePath = null;
		if (fileFolderPath.startsWith("/") || fileFolderPath.indexOf(":") > 0) {
			// 如果是绝对路径
			absolutePath = fileFolderPath;
		} else {
			// 如果是相对路径 则相对的是是项目的webroot目录
			absolutePath = getClass().getResource(SPRIT).getPath()
					.replace("WEB-INF/classes/", "")
					+ fileFolderPath;
		}
		FileUtils.createDirectoryRecursively(absolutePath);
		return new File(absolutePath);
	}

	/**
	 * Description:生成上传文件要保存的目录
	 * 
	 * @author 唐海洋
	 * @Version 1.0 2016-8-9下午5:35:19
	 * @param userParams
	 * @return 返回相对于用户目录的文件保存目录，如：20160809/
	 */
	protected String generateUploadDirPath() {
		return DateUtils.format(new Date(), "yyyyMMdd") + SPRIT;
	}

	/**
	 * Description:生成随机的文件名称
	 * 
	 * @author 唐海洋
	 * @Version 1.0 2016-8-9下午5:36:36
	 * @param ext
	 *            文件后缀
	 * @return 新的文件名，不能包含中文
	 */
	protected String generateNewFileName(String ext) {
		SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("HHmmss");
		ext = "jpg"; // 有的格式图片上传不了，把所有格式的图片转换为这样就可以了。
		return fileNameDateFormat.format(new Date())
				+ UUID.randomUUID().toString().substring(0, 8) + "." + ext;
	}
}